using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;

namespace Zsa.Emulation.PPU
{
    /// <summary>
    /// The palette colors
    /// </summary>
    public class ColorPaletteSettings
    {

        #region Static Methods
        /// <summary>
        /// Creates the default palette colors using rgb int.
        /// </summary>
        /// <returns></returns>
        public static ColorPaletteSettings CreateDefault()
        {
            return new ColorPaletteSettings(
                new int[] 
                {
                    Color.FromArgb(0x757575).ToArgb(),
                    Color.FromArgb(0x271B8F).ToArgb(),
                    Color.FromArgb(0x0000AB).ToArgb(),
                    Color.FromArgb(0x47009F).ToArgb(),
                    Color.FromArgb(0x8F0077).ToArgb(),
                    Color.FromArgb(0xAB0013).ToArgb(),
                    Color.FromArgb(0xA70000).ToArgb(),
                    Color.FromArgb(0x7F0B00).ToArgb(),
                    Color.FromArgb(0x432F00).ToArgb(),
                    Color.FromArgb(0x004700).ToArgb(),
                    Color.FromArgb(0x005100).ToArgb(),
                    Color.FromArgb(0x003F17).ToArgb(),
                    Color.FromArgb(0x1B3F5F).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0xBCBCBC).ToArgb(),
                    Color.FromArgb(0x0073EF).ToArgb(),
                    Color.FromArgb(0x233BEF).ToArgb(),
                    Color.FromArgb(0x8300F3).ToArgb(),
                    Color.FromArgb(0xBF00BF).ToArgb(),
                    Color.FromArgb(0xE7005B).ToArgb(),
                    Color.FromArgb(0xDB2B00).ToArgb(),
                    Color.FromArgb(0xCB4F0F).ToArgb(),
                    Color.FromArgb(0x8B7300).ToArgb(),
                    Color.FromArgb(0x009700).ToArgb(),
                    Color.FromArgb(0x00AB00).ToArgb(),
                    Color.FromArgb(0x00933B).ToArgb(),
                    Color.FromArgb(0x00838B).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0xFFFFFF).ToArgb(),
                    Color.FromArgb(0x3FBFFF).ToArgb(),
                    Color.FromArgb(0x5F97FF).ToArgb(),
                    Color.FromArgb(0xA78BFD).ToArgb(),
                    Color.FromArgb(0xF77BFF).ToArgb(),
                    Color.FromArgb(0xFF77B7).ToArgb(),
                    Color.FromArgb(0xFF7763).ToArgb(),
                    Color.FromArgb(0xFF9B3B).ToArgb(),
                    Color.FromArgb(0xF3BF3F).ToArgb(),
                    Color.FromArgb(0x83D313).ToArgb(),
                    Color.FromArgb(0x4FDF4B).ToArgb(),
                    Color.FromArgb(0x58F898).ToArgb(),
                    Color.FromArgb(0x00EBDB).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0xFFFFFF).ToArgb(),
                    Color.FromArgb(0xABE7FF).ToArgb(),
                    Color.FromArgb(0xC7D7FF).ToArgb(),
                    Color.FromArgb(0xD7CBFF).ToArgb(),
                    Color.FromArgb(0xFFC7FF).ToArgb(),
                    Color.FromArgb(0xFFC7DB).ToArgb(),
                    Color.FromArgb(0xFFBFB3).ToArgb(),
                    Color.FromArgb(0xFFDBAB).ToArgb(),
                    Color.FromArgb(0xFFE7A3).ToArgb(),
                    Color.FromArgb(0xE3FFA3).ToArgb(),
                    Color.FromArgb(0xABF3BF).ToArgb(),
                    Color.FromArgb(0xB3FFCF).ToArgb(),
                    Color.FromArgb(0x9FFFF3).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb(),
                    Color.FromArgb(0x000000).ToArgb()
                }
            );
        }
        #endregion

        #region Fields
        /// <summary>
        /// The total number of colors.
        /// </summary>
        public const int TotalColors = 64;

        /// <summary>
        /// The colors
        /// </summary>
        private readonly int[] _Colors;
        #endregion Fields

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="T:PaletteSettings"/> class.
        /// </summary>
        /// <param name="colors">The colors.</param>
        [CLSCompliant(false)]
        public ColorPaletteSettings(int[] colors)
        {
            if (colors == null)
            {
                throw new ArgumentNullException("colors");
            }
            if (colors.Length != TotalColors)
            {
                throw new IndexOutOfRangeException("colors");
            }
            _Colors = colors;
        }
        #endregion Constructor

        #region Methods

        ///// <summary>
        ///// Changes the color.
        ///// </summary>
        ///// <param name="color">The color.</param>
        ///// <param name="newColor">The new color.</param>
        //public void ChangeColor(NesColors color,
        //    byte newColor)
        //{
        //    ChangeColor(color, (uint)newColor);
        //}

        /// <summary>
        /// Changes the color.
        /// </summary>
        /// <param name="color">The color.</param>
        /// <param name="newColor">The new color.</param>
        public void ChangeColor(NesColors color,
            int newColor)
        {
            ChangeColor(color,Color.FromArgb(newColor));
        }

        /// <summary>
        /// Changes the color.
        /// </summary>
        /// <param name="color">The color.</param>
        /// <param name="newColor">The new color.</param>
        /// <returns></returns>
        [CLSCompliant(false)]
        public void ChangeColor(NesColors color,
            Color newColor)
        {
            int _ColorIndex = (int)color;
            if ( _ColorIndex < 0 || _ColorIndex > 63 )
            {
                throw new ArgumentOutOfRangeException("color", color, "Invalid nes color !");
            }
            _Colors[_ColorIndex] = newColor.ToArgb();
        }


        /// <summary>
        /// Fills the color palette.
        /// </summary>
        /// <param name="palette">The palette.</param>
        public void FillColorPalette(ColorPalette palette)
        {
            FillColorPalette(palette, Color.Black);
        }

        /// <summary>
        /// Fills the color palette.
        /// </summary>
        /// <param name="palette">The palette.</param>
        /// <param name="emptyColor">The color to use for positions in palette.</param>
        public void FillColorPalette(ColorPalette palette, Color emptyColor)
        {
            // Check to see if palette is null.
            if (palette == null)
            {
                throw new ArgumentNullException("palette");
            }
            // Get the palette length.
            int _PaletteSize = palette.Entries.Length;
            // Make sure palette is large enough.
            if (_PaletteSize < TotalColors)
            {
                throw new ArgumentException("The palette is to small !", "palette");
            }
            // Loop through the colors.
            for (int _TempIndex = 0; _TempIndex < _Colors.Length; _TempIndex++)
            { 
               // palette.Entries[_TempIndex] = _Colors[_TempIndex];
            }
            // Set the empty colors.
            for (int _TempIndex = _Colors.Length; _TempIndex < palette.Entries.Length; _TempIndex++)
            {
                palette.Entries[_TempIndex] = emptyColor;
            }

        }

        #endregion Methods

        #region Properties
        /// <summary>
        /// Gets the <see cref="T:Int32"/> with the specified color.
        /// </summary>
        /// <value></value>
        public int this[NesColors color]
        {
            get
            {
                return this[(int)color];
            }
        }


        /// <summary>
        /// Gets the <see cref="T:Int32"/> with the specified color.
        /// </summary>
        /// <value></value>
        public int this[int color]
        {
            get
            {
                //int _ColorIndex = (int)color;
                if (color < 64)
                {
                    return _Colors[color];
                }
                return Color.Transparent.ToArgb();
                throw new ArgumentOutOfRangeException("color", color, "Invalid nes color !");

                
            }
        }
        #endregion Properties


        internal unsafe void SetPointers(byte* _Buffer, byte size, byte* _R, byte* _G, byte* _B, byte* _A)
        {
  
        }
    }




}
